home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / midas060 / src / pas.asm < prev    next >
Encoding:
Assembly Source File  |  1997-01-16  |  22.3 KB  |  867 lines

  1. ;*      PAS.ASM
  2. ;*
  3. ;* Pro Audio Spectrum Sound Device
  4. ;*
  5. ;* $Id: pas.asm,v 1.3 1997/01/16 18:41:59 pekangas Exp $
  6. ;*
  7. ;* Copyright 1996,1997 Housemarque Inc.
  8. ;*
  9. ;* This file is part of the MIDAS Sound System, and may only be
  10. ;* used, modified and distributed under the terms of the MIDAS
  11. ;* Sound System license, LICENSE.TXT. By continuing to use,
  12. ;* modify or distribute this file you indicate that you have
  13. ;* read the license and understand and accept it fully.
  14. ;*
  15.  
  16. ;* NOTE! A lot of this code is ripped more or less directly from the PAS
  17. ;* SDK and might therefore seem messy.
  18. ;* I really do not understand some parts of this code... Perhaps I'll clear
  19. ;* it up some day when I have time.
  20. ;* (PK)
  21.  
  22. ;* Update: The above probably won't ever happen though. The statement has been
  23. ;* there over a year now, through three major revisions of the Sound Device..
  24.  
  25.  
  26.  
  27. IDEAL
  28. P386
  29. JUMPS
  30.  
  31. INCLUDE "pas.inc"
  32. INCLUDE "lang.inc"
  33. INCLUDE "errors.inc"
  34. INCLUDE "sdevice.inc"
  35. INCLUDE "dsm.inc"
  36. INCLUDE "mixsd.inc"
  37. IFDEF __DPMI__
  38. INCLUDE "dpmi.inc"
  39. ENDIF
  40.  
  41.  
  42.  
  43. ;/***************************************************************************\
  44. ;*       enum pasFunctIDs
  45. ;*       ----------------
  46. ;* Description:  ID numbers for PAS Sound Device functions
  47. ;\***************************************************************************/
  48.  
  49. ENUM    pasFunctIDs \
  50.         ID_pasDetect = ID_pas, \
  51.         ID_pasInit, \
  52.         ID_pasClose
  53.  
  54.  
  55.  
  56. ;/***************************************************************************\
  57. ;*      enumpasCardTypes
  58. ;*      ----------------
  59. ;* Description: Sound Card type number for Pro Audio Spectrum Sound Device
  60. ;\***************************************************************************/
  61.  
  62. ENUM    pasCardTypes \
  63.         pasAutoType = 0, \              ; autodetect card type
  64.         pasNormal, \                    ; Pro Audio Spectrum
  65.         pasPlus, \                      ; Pro Audio Spectrum plus
  66.         pas16                           ; Pro Audio Spectrum 16
  67.  
  68.  
  69.  
  70.  
  71. DATASEG
  72.  
  73.  
  74. D_int   pasSpeed                        ; output rate value
  75. D_int   pasRate                         ; actual output rate
  76. D_int   pasMode                         ; output mode
  77.  
  78. IFDEF __DPMI__
  79. regs            dpmiRealCallRegs  ?     ; DPMI interrupt calling registers
  80. ENDIF
  81.  
  82.  
  83. IFDEF __PASCAL__
  84. EXTRN   PAS : SoundDevice
  85. ENDIF
  86.  
  87.  
  88. IDATASEG
  89.  
  90. PASCONFIGBITS = sdUsePort or sdUseIRQ or sdUseDMA or sdUseMixRate or \
  91.         sdUseOutputMode or sdUseDSM
  92. PASMODEBITS = sdMono or sdStereo or sd8bit or sd16bit
  93.  
  94.  
  95.  
  96. ; If compiling for Pascal, Sound Device name is pasSD, from which the data
  97. ; will be copied to Sound Device PAS, defined in Pascal.
  98.  
  99. IFDEF   __PASCAL__
  100. SDNAM           equ     pasSD
  101. ELSE
  102. SDNAM           equ     PAS
  103. ENDIF
  104.  
  105. GLOBAL  LANG SDNAM : SoundDevice
  106.  
  107. SDNAM   SoundDevice     < \
  108.  0,\
  109.  PASCONFIGBITS,\
  110.  388h, 15, 5,\
  111.  pasAutoType, 3,\
  112.  PASMODEBITS,\
  113.  ptr_to pasSDName,\
  114.  ptr_to pasCardNames,\
  115.  4, ptr_to pasPortAddresses,\
  116.  ptr_to pasDetect,\
  117.  ptr_to pasInit,\
  118.  ptr_to pasClose,\
  119.  ptr_to dsmGetMixRate,\
  120.  ptr_to mixsdGetMode,\
  121.  ptr_to mixsdOpenChannels,\
  122.  ptr_to dsmCloseChannels,\
  123.  ptr_to dsmClearChannels,\
  124.  ptr_to dsmMute,\
  125.  ptr_to dsmPause,\
  126.  ptr_to dsmSetMasterVolume,\
  127.  ptr_to dsmGetMasterVolume,\
  128.  ptr_to mixsdSetAmplification,\
  129.  ptr_to mixsdGetAmplification,\
  130.  ptr_to dsmPlaySound,\
  131.  ptr_to dsmReleaseSound\
  132.  ptr_to dsmStopSound,\
  133.  ptr_to dsmSetRate,\
  134.  ptr_to dsmGetRate,\
  135.  ptr_to dsmSetVolume,\
  136.  ptr_to dsmGetVolume,\
  137.  ptr_to dsmSetSample,\
  138.  ptr_to dsmGetSample,\
  139.  ptr_to dsmSetPosition,\
  140.  ptr_to dsmGetPosition,\
  141.  ptr_to dsmGetDirection,\
  142.  ptr_to dsmSetPanning,\
  143.  ptr_to dsmGetPanning,\
  144.  ptr_to dsmMuteChannel,\
  145.  ptr_to dsmAddSample,\
  146.  ptr_to dsmRemoveSample,\
  147.  ptr_to mixsdSetUpdRate,\
  148.  ptr_to mixsdStartPlay,\
  149.  ptr_to mixsdPlay >
  150.  
  151.  
  152. pasSDName       DB      "Pro Audio Spectrum series Sound Device v1.30", 0
  153.  
  154.                 ; *!!*
  155. pasCardNames    DD      ptr_to pasName
  156.                 DD      ptr_to pasPlusName
  157.                 DD      ptr_to pas16Name
  158.  
  159. pasName         DB      "Pro Audio Spectrum", 0
  160. pasPlusName     DB      "Pro Audio Spectrum plus", 0
  161. pas16Name       DB      "Pro Audio Spectrum 16", 0
  162.  
  163. IFDEF __16__
  164. pasPortAddresses  DW    388h, 384h, 38Ch, 288h
  165. ELSE
  166. pasPortAddresses  DD    388h, 384h, 38Ch, 288h
  167. ENDIF
  168.  
  169.  
  170.  
  171.  
  172. DATASEG
  173.  
  174.  
  175. D_int   mvTranslateCode                 ; I/O base xor default_base
  176.  
  177. D_farptr mvhwShadowPointer              ; pointer to shadow register values
  178. IFDEF __32__
  179.                 DW      0               ; kluge - 32-bit DPMI functions assume
  180.                                         ; 32-bit selector values with upper
  181.                                         ; 16 bits zero
  182. ENDIF
  183.  
  184.  
  185.  
  186.  
  187. CODESEG
  188.  
  189.  
  190.  
  191. PUBLIC    pasDetect
  192. PUBLIC    pasInit
  193. PUBLIC    pasClose
  194.  
  195.  
  196.  
  197.  
  198. PROC    pasSearchHW     _funct
  199. USES    _si,_di,_bx
  200.  
  201. ;
  202. ; calculate the translation code
  203. ;
  204.         mov     [PAS.port],_di
  205.  
  206.         xor     _di,DEFAULT_BASE        ; di holds the translation code
  207.  
  208. ;
  209. ; grab the version # in the interrupt mask. The top few bits hold the version #
  210. ;
  211.         mov     _dx,INTRCTLR            ; board ID is in MSB 3 bits
  212.         xor     _dx,_di                 ; adjust to other address
  213.     in    al,dx
  214.     cmp    al,-1            ; bus float meaning not present?
  215.     je    @@bad            ; yes, there is no card here
  216.  
  217.     mov    ah,al            ; save an original copy
  218.     xor    al,fICrevbits        ; the top bits wont change
  219.  
  220.     out    dx,al            ; send out the inverted bits
  221.         jmp short $+2
  222.         jmp short $+2
  223.     in    al,dx            ; get it back...
  224.  
  225.     cmp    al,ah            ; both should match now...
  226.     xchg    al,ah            ; (restore without touching the flags)
  227.     out    dx,al
  228.  
  229.     jnz    @@bad            ; we have a bad board
  230.  
  231. ;
  232. ; We do have hardware!
  233. ;
  234.  
  235.         mov     _ax,1                   ; a valid PAS card found
  236.         jmp     @@done
  237.  
  238.  
  239. @@bad:
  240.         xor     _ax,_ax                 ; we got here due to a bad board
  241.  
  242. @@done:
  243.     ret
  244. ENDP
  245.  
  246.  
  247.  
  248. PROC    pasSetVersion   _funct
  249. USES    _di,_bx
  250.  
  251.         mov     _di,[PAS.port]
  252.         xor     _di,DEFAULT_BASE        ; di holds the translation code
  253.  
  254. ;
  255. ; grab the version # in the interrupt mask. The top few bits hold the version #
  256. ;
  257.         mov     _dx,INTRCTLR            ; board ID is in MSB 3 bits
  258.         xor     _dx,_di                 ; adjust to other address
  259.     in    al,dx
  260.     cmp    al,-1            ; bus float meaning not present?
  261.     je    @@bad            ; yes, there is no card here
  262.  
  263.     mov    ah,al            ; save an original copy
  264.     xor    al,fICrevbits        ; the top bits wont change
  265.  
  266.     out    dx,al            ; send out the inverted bits
  267.     jmp    $+2
  268.     jmp    $+2
  269.     in    al,dx            ; get it back...
  270.  
  271.     cmp    al,ah            ; both should match now...
  272.     xchg    al,ah            ; (restore without touching the flags)
  273.     out    dx,al
  274.  
  275.     jnz    @@bad            ; we have a bad board
  276.  
  277.         and     _ax,fICrevbits          ; isolate the ID bits & clear AH
  278.         shr     al,fICrevshr            ; shift the bits into a meaningful
  279.                                         ; position (least signficant bits)
  280.         mov     _si,_ax                 ; save the version #
  281. ;
  282. ; We do have hardware! Load the product bit definitions
  283. ;
  284.         test    al,al                   ; is this the first version of h/w?
  285.         jz      @@vpas                  ; yes, it's a standard PAS
  286.  
  287.         ; The card is either PAS plus or PAS 16. The only thing that
  288.         ; actually matters here is whether the card has a 16-bit DAC or
  289.         ; not. If yes, it's a PAS 16, otherwise assume it's PAS plus.
  290.  
  291. ;
  292. ; determine the CDROM drive type, FM chip, 8/16 bit DAC, and mixer
  293. ;
  294.         mov     _dx,SLAVEMODRD          ; check for the CDPC
  295.         xor     _dx,_di                 ; modify via the translate code
  296.     in    al,dx
  297.  
  298.     test    al,bSMRDdactyp        ; 16 bit DAC?
  299.         jz      @@vpasplus              ; no, its an 8 bit DAC - PAS plus
  300.  
  301.         ; neither PAS or PAS plus - assume PAS 16
  302.         mov     [PAS.cardType],pas16
  303.         mov     [PAS.modes],sdStereo or sdMono or sd16bit or sd8bit
  304.         jmp     @@ok
  305.  
  306. @@vpas:
  307.         ; standard PAS card
  308.         mov     [PAS.cardType],pasNormal
  309.         mov     [PAS.modes],sdStereo or sdMono or sd8bit
  310.         jmp     @@ok
  311.  
  312. @@vpasplus:
  313.         ; PAS plus
  314.         mov     [PAS.cardType],pasPlus
  315.         mov     [PAS.modes],sdStereo or sdMono or sd8bit
  316.         jmp     @@ok
  317.  
  318.  
  319. @@bad:
  320.         mov     _ax,errSDFailure        ; bad card - SD hardware failure
  321.         jmp     @@done
  322.  
  323. @@ok:
  324.         xor     _ax,_ax
  325.  
  326. @@done:
  327.         ret
  328. ENDP
  329.  
  330.  
  331.  
  332.  
  333. ;/***************************************************************************\
  334. ;*
  335. ;* Function:    int pasDetect(int *result);
  336. ;*
  337. ;* Description: Detects Pro Audio Spectrum soundcard
  338. ;*
  339. ;* Returns:     MIDAS error code.
  340. ;*              1 stored to *result if PAS was detected, 0 if not.
  341. ;*
  342. ;\***************************************************************************/
  343.  
  344. PROC    pasDetect       _funct  result : _ptr
  345. USES    _si,_di,_bx
  346.  
  347.         ; For some oddball reason this function does not work with
  348.         ; Borland Pascal 7 in Protected mode. Therefore when compiling for
  349.         ; BP7 Protect Mode this function just stores 0 in *result and
  350.         ; exits. Therefore it is important to have a reasonable setup like
  351.         ; midasConfig() where the user can enter the correct values for
  352.         ; Port, IRQ and DMA if they differ from the default ones.
  353.  
  354. IFDEF __DPMI__
  355. IFDEF __PASCAL__
  356. ;NOPASDETECT = 1
  357. ENDIF
  358. ENDIF
  359.  
  360. IFDEF NOPASDETECT
  361.  
  362.         les     bx,[result]             ; no detection for BP7 protected mode
  363.         mov     [word es:bx],0
  364.         xor     ax,ax
  365.         ret
  366. ELSE
  367.  
  368. IFDEF __DPMI__
  369.         ; use DPMI to emulate real mode interrupt:
  370.  
  371.         mov     [regs.rEAX],0BC00h      ; make sure MVSOUND.SYS is loaded
  372.         mov     [regs.rEBX],'??'        ; this is our way of knowing if the
  373.         mov     [regs.rECX],0           ; hardware is actually present.
  374.         mov     [regs.rEDX],0
  375.         mov     [regs.rSP],0
  376.         mov     [regs.rSS],0
  377. IFDEF __16__
  378.         call    dpmiRealModeInt LANG, 2Fh, seg regs offset regs
  379. ELSE
  380.         call    dpmiRealModeInt LANG, 2Fh, offset regs
  381. ENDIF
  382.         test    _ax,_ax
  383.         jnz     @@err
  384.  
  385.         mov     bx,[word regs.rEBX]     ; build the result
  386.         xor     bx,[word regs.rECX]
  387.         xor     bx,[word regs.rEDX]
  388.  
  389. ELSE
  390.         mov     ax,0BC00H               ; make sure MVSOUND.SYS is loaded
  391.     mov    bx,'??'                 ; this is our way of knowing if the
  392.     xor    cx,cx            ; hardware is actually present.
  393.     xor    dx,dx
  394.         int     2Fh                     ; get the ID pattern
  395.     xor    bx,cx            ; build the result
  396.     xor    bx,dx
  397. ENDIF
  398.  
  399.         cmp     bx,'MV'                 ; if not here, exit...
  400.         jne     @@nopas
  401.  
  402. ;
  403. ; get the MVSOUND.SYS specified DMA and IRQ channel
  404. ;
  405. IFDEF __DPMI__
  406.         ; use DPMI to emulate real mode interrupt:
  407.         mov     [regs.rEAX],0BC04h      ; get the DMA and IRQ numbers
  408.         mov     [regs.rSP],0
  409.         mov     [regs.rSS],0
  410. IFDEF __16__
  411.         call    dpmiRealModeInt LANG, 2Fh, seg regs offset regs
  412. ELSE
  413.         call    dpmiRealModeInt LANG, 2Fh, offset regs
  414. ENDIF
  415.         test    _ax,_ax
  416.         jnz     @@err
  417.         xor     _ax,_ax
  418.         mov     al,[byte regs.rEBX]
  419.         mov     [PAS.DMA],_ax
  420.         mov     al,[byte regs.rECX]
  421.         mov     [PAS.IRQ],_ax
  422. ELSE
  423.         mov     ax,0BC04h               ; get the DMA and IRQ numbers
  424.         int     2Fh
  425.         xor     bh,bh
  426.         mov     [PAS.DMA],bx            ; save the correct DMA & IRQ
  427.         xor     ch,ch
  428.         mov     [PAS.IRQ],cx
  429. ENDIF
  430.  
  431.  
  432.         ; now search for the hardware port address:
  433.  
  434.  
  435.     ; search the default address
  436.  
  437.         mov     _di,DEFAULT_BASE        ; try the first address
  438.     call    pasSearchHW
  439.         cmp     _ax,1
  440.         je      @@found
  441.  
  442.     ; search the first alternate address
  443.  
  444.         mov     _di,ALT_BASE_1          ; try the first alternate
  445.     call    pasSearchHW
  446.         cmp     _ax,1
  447.         je      @@found
  448.  
  449.     ; search the second alternate address
  450.  
  451.         mov     _di,ALT_BASE_2          ; try the second alternate
  452.     call    pasSearchHW
  453.         cmp     _ax,1
  454.         je      @@found
  455.  
  456.     ; search the third, or user requested alternate address
  457.  
  458.         mov     _di,ALT_BASE_3          ; try the third alternate
  459.     call    pasSearchHW        ; pass the third A, or user I/O
  460.         cmp     _ax,1
  461.         jne     @@nopas
  462.  
  463. @@found:
  464.         LOADPTR es,_bx,[result]         ; write 1 to *result - PAS detected
  465.         mov     [_int _esbx],1          ; succesfully
  466.  
  467.         cmp     [PAS.cardType],pasAutoType      ; has the card type been set?
  468.         jne     @@verset                        ; if yes, do not detect
  469.  
  470.         call    pasSetVersion           ; set card version to card structure
  471.         test    _ax,_ax
  472.         jnz     @@err
  473.  
  474. @@verset:
  475.         cmp     [PAS.cardType],pasNormal        ; normal PAS or PAS plus?
  476.         je      @@no16modes                     ; if yes, 16-bit modes are
  477.         cmp     [PAS.cardType],pasPlus          ; not available
  478.         je      @@no16modes
  479.  
  480.         ; All output modes available:
  481.         mov     [PAS.modes],sd8bit or sd16bit or sdMono or sdStereo
  482.         jmp     @@ok
  483.  
  484. @@no16modes:
  485.         ; No 16-bit modes available:
  486.         mov     [PAS.modes],sd8bit or sdMono or sdStereo
  487.         jmp     @@ok
  488.  
  489. @@nopas:
  490.         LOADPTR es,_bx,[result]
  491.         mov     [_int _esbx],0          ; no PAS found
  492.  
  493. @@ok:
  494.         xor     _ax,_ax                 ; success
  495.         jmp     @@done
  496.  
  497. @@err:
  498.         ERROR   ID_pasDetect
  499.  
  500. @@done:
  501.     ret
  502. ENDIF
  503. ENDP
  504.  
  505.  
  506.  
  507.  
  508. ;/***************************************************************************\
  509. ;*
  510. ;* Function:    int pasInit(unsigned mixRate, unsigned mode);
  511. ;*
  512. ;* Description: Initializes Pro Audio Spectrum
  513. ;*
  514. ;* Input:       unsigned mixRate        mixing rate
  515. ;*              unsigned mode           output mode (see enum sdMode)
  516. ;*
  517. ;* Returns:     MIDAS error code
  518. ;*
  519. ;\***************************************************************************/
  520.  
  521. PROC    pasInit         _funct  mixRate : _int, mode : _int
  522. USES    es,_si,_di,_bx
  523.  
  524.         mov     _di,[PAS.port]          ; PAS I/O port
  525.     call    pasSearchHW        ; search for hardware at this port
  526.         cmp     _ax,1
  527.         je      @@hwok
  528.  
  529.         mov     _ax,errSDFailure        ; Sound Device hardware failure
  530.         jmp     @@err
  531.  
  532. @@hwok:
  533.         xor     _di,DEFAULT_BASE        ; save port XOR default port
  534.         mov     [mvTranslateCode],_di
  535.  
  536.         cmp     [PAS.cardType],pasAutoType      ; has card type been set?
  537.         jne     @@typeset
  538.  
  539.         call    pasSetVersion           ; set card type to card structure
  540.  
  541.  
  542. @@typeset:
  543.         mov     [pasMode],0
  544.  
  545.     test    [mode],sd8bit        ; force 8-bit?
  546.     jnz    @@8b
  547.         cmp     [PAS.cardType],pas16    ; is the card type PAS 16?
  548.         jne     @@8b                    ; if not, use 8-bit output
  549.         or      [pasMode],sd16bit       ; use 16 bits
  550.     jmp    @@bit
  551. @@8b:    or    [pasMode],sd8bit
  552.  
  553. @@bit:    test    [mode],sdMono        ; force mono?
  554.     jnz    @@mono
  555.     or    [pasMode],sdStereo    ; if not, use stereo
  556.     jmp    @@mst
  557. @@mono: or    [pasMode],sdMono
  558.  
  559. @@mst:
  560.  
  561.         ; from PAS SDK...
  562.  
  563. IFDEF __DPMI__
  564.         ; Get pointer to PAS driver shadow hardware register table:
  565.  
  566.         mov     [regs.rEAX],0BC02h
  567.         mov     [regs.rSS],0
  568.         mov     [regs.rSP],0
  569. IFDEF __16__
  570.         call    dpmiRealModeInt LANG, 2Fh, seg regs offset regs
  571. ELSE
  572.         call    dpmiRealModeInt LANG, 2Fh, offset regs
  573. ENDIF
  574.         test    _ax,_ax
  575.         jnz     @@err
  576.         cmp     [word regs.rEAX],'MV'
  577.         je      @@mvok
  578.  
  579.         mov     _ax,errSDFailure
  580.         jmp     @@err
  581.  
  582. @@mvok:
  583.         ; regs.rEDX:regs.rEBX now contains a real mode pointer to the PAS
  584.         ; hardware status table. Now we must build a DPMI descriptor to
  585.         ; the data area and store it plus offset 0 to mvhwShadowPointer:
  586.  
  587.         mov     [_int mvhwShadowPointer],0      ; offset 0
  588.  
  589.         ; Allocate descriptor from DPMI:
  590. IFDEF __16__
  591.         call    dpmiAllocDescriptor LANG, seg mvhwShadowPointer \
  592.                 (offset mvhwShadowPointer+2)
  593. ELSE
  594.         call    dpmiAllocDescriptor LANG, offset mvhwShadowPointer+4
  595. ENDIF
  596.         test    _ax,_ax
  597.         jnz     @@err
  598.  
  599.         xor     eax,eax
  600.         xor     ebx,ebx
  601.         mov     ax,[word regs.rEDX]     ; eax = linear address of hardware
  602.         shl     eax,4                   ; status table
  603.         mov     bx,[word regs.rEBX]
  604.         add     eax,ebx
  605.  
  606.         ; Set segment base address:
  607.         call    dpmiSetSegmentBase LANG, [_int mvhwShadowPointer+INTSIZE], eax
  608.         test    _ax,_ax
  609.         jnz     @@err
  610.  
  611.         ; Set correct segment limit:
  612.         mov     eax,(SIZE MVState) - 1
  613.         call    dpmiSetSegmentLimit LANG, [_int mvhwShadowPointer+INTSIZE], \
  614.                 eax
  615.         test    _ax,_ax
  616.         jnz     @@err
  617. ELSE
  618.     mov    ax,0BC02H        ; get the pointer
  619.     int    2fh
  620.     cmp    ax,'MV'                 ; busy or intercepted
  621.     jnz    @@spdone
  622.  
  623.     mov    [word mvhwShadowPointer+0],bx
  624.     mov    [word mvhwShadowPointer+2],dx
  625. ENDIF
  626. ;
  627. @@spdone:
  628.  
  629.         mov     _dx,INTRCTLRST                 ; flush any pending PCM irq
  630.         xor     _dx,[mvTranslateCode]          ; xlate the board address
  631.     out    dx,al
  632.  
  633.  
  634.     ; calculate sample rate
  635.  
  636.         les     _di,[mvhwShadowPointer]
  637.  
  638.     mov    eax,1193180
  639.     xor    edx,edx
  640. IFDEF __16__
  641.         xor     ebx,ebx
  642. ENDIF
  643.         mov     _bx,[mixRate]
  644.     div    ebx
  645.         mov     [es:_di+MVState._samplerate],ax ; save output speed
  646.         mov     [pasSpeed],_ax
  647.  
  648.     test    [pasMode],sdStereo
  649.     jz    @@nostereo
  650.         mov     _ax,[pasSpeed]
  651.         shr     _ax,1                   ; multiply output rate with 2 if
  652.         mov     [pasSpeed],_ax          ; stereo
  653.         mov     [es:_di+MVState._samplerate],ax
  654.  
  655. @@nostereo:
  656.     mov    eax,1193180
  657.     xor    edx,edx
  658. IFDEF __16__
  659.         xor     ebx,ebx
  660. ENDIF
  661.         mov     _bx,[pasSpeed]          ; calculate actual output rate
  662.     div    ebx
  663.  
  664.     test    [pasMode],sdStereo
  665.     jz    @@nostereo2        ; divide with 2 if stereo to get
  666.     shr    eax,1            ; actual output rate
  667.  
  668. @@nostereo2:
  669.         mov     [pasRate],_ax
  670.  
  671.     mov    al,00110110b        ; 36h Timer 0 & square wave
  672.         mov     _dx,TMRCTLR
  673.         xor     _dx,[mvTranslateCode]   ; xlate the board address
  674.  
  675.     cli
  676.  
  677.     out    dx,al            ; setup the mode, etc
  678.         mov     [es:_di+MVState._tmrctlr],al
  679.  
  680.         mov     ax,[es:_di+MVState._samplerate] ; pre-calculated & saved in
  681.         mov     _dx,SAMPLERATE                  ; prior code
  682.         xor     _dx,[mvTranslateCode]  ; xlate the board address
  683.     out    dx,al            ; output the timer value
  684.  
  685.         jmp short $+2
  686.  
  687.     xchg    ah,al
  688.     out    dx,al
  689.     sti
  690.  
  691.         mov     _dx,CROSSCHANNEL
  692.         xor     _dx,[mvTranslateCode]
  693.  
  694.         mov     al,[es:_di+MVState._crosschannel]    ; Stop PAS' DMA transfer
  695.     or    al,bCCdrq
  696.         mov     [es:_di+MVState._crosschannel],al
  697.     out    dx,al
  698.  
  699.         ; Take care of common initialization for all mixing Sound Devices:
  700.         push    es
  701.         call    mixsdInit LANG, [pasRate], [pasMode], [PAS.DMA]
  702.         pop     es
  703.         test    _ax,_ax
  704.         jnz     @@err
  705.  
  706.     test    [pasMode],sd16bit
  707.     jz    @@no16bit
  708.         mov     _cx,(((NOT(bSC216bit+bSC212bit) AND 0FFh)*256) + bSC216bit)
  709.         mov     _dx,SYSCONFIG2
  710.         xor     _dx,[mvTranslateCode]  ; xlate the board address
  711.     in    al,dx
  712.     and    al,ch            ; clear the bits
  713.     or    al,cl            ; set the appropriate bits
  714.     out    dx,al
  715. @@no16bit:
  716.     mov    al,bCCmono        ; get the stereo/mono mask bit
  717.     test    [pasMode],sdStereo
  718.     jz    @@nostereox
  719.     sub    al,al
  720. @@nostereox:
  721.     or    al,bCCdac        ; get the direction bit mask
  722.     or    al,bCCenapcm        ; enable the PCM state machine
  723.         mov     _dx,CROSSCHANNEL
  724.         xor     _dx,[mvTranslateCode]  ; xlate the board address
  725.  
  726.     mov    ah,0fh + bCCdrq     ; get a mask to load non PCM bits
  727.         and     ah,[es:_di+MVState._crosschannel]
  728.                     ; grab all but PCM/DRQ/MONO/DIRECTION
  729.     or    al,ah            ; merge the two states
  730.     xor    al,bCCenapcm        ; disable the PCM bit
  731.     out    dx,al            ; send to the hardware
  732.         jmp short $+2
  733.     xor    al,bCCenapcm        ; enable the PCM bit
  734.     out    dx,al            ; send to the hardware
  735.         mov     [es:_di+MVState._crosschannel],al ; and save the new state
  736. ;
  737. ; Setup the audio filter sample bits
  738. ;
  739.         mov     al,[es:_di+MVState._audiofilt]
  740.     or    al,(bFIsrate+bFIsbuff)    ; enable the sample count/buff counters
  741.         mov     _dx,AUDIOFILT
  742.         xor     _dx,[mvTranslateCode]  ; xlate the board address
  743.     out    dx,al
  744.         mov     [es:_di+MVState._audiofilt],al
  745.  
  746.         mov     al,[es:_di+MVState._crosschannel] ; get the state
  747.         mov     _dx,CROSSCHANNEL
  748.         xor     _dx,[mvTranslateCode]  ; xlate the board address
  749.     or    al,bCCdrq        ; set the DRQ bit to control it
  750.     out    dx,al
  751.         mov     [es:_di+MVState._crosschannel],al ; and save the new state
  752.  
  753. @@ok:
  754.         xor     _ax,_ax                 ; success
  755.         jmp     @@done
  756.  
  757. @@err:
  758.         ERROR   ID_pasInit
  759.  
  760. @@done:
  761.     ret
  762. ENDP
  763.  
  764.  
  765.  
  766.  
  767. ;/***************************************************************************\
  768. ;*
  769. ;* Function:    int pasClose()
  770. ;*
  771. ;* Description: Uninitializes Pro Audio Spectrum
  772. ;*
  773. ;* Returns:     MIDAS error code
  774. ;*
  775. ;\***************************************************************************/
  776.  
  777. PROC    pasClose        _funct
  778. USES    es,_di,_bx
  779.  
  780.         les     _di,[mvhwShadowPointer]
  781. ;
  782. ; clear the audio filter sample bits
  783. ;
  784.         mov     _dx,AUDIOFILT
  785.         xor     _dx,[mvTranslateCode]     ; xlate the board address
  786.     cli            ; drop dead...
  787.         mov     al,[es:_di+MVState._audiofilt]    ; get the state
  788.     and    al,not (bFIsrate+bFIsbuff) ; flush the sample timer bits
  789.         mov     [es:_di+MVState._audiofilt],al    ; save the new state
  790.     out    dx,al
  791.  
  792.     test    [pasMode],sd16bit
  793.     jz    @@no16bit
  794.  
  795. ;
  796. ; disable the 16 bit stuff
  797. ;
  798.         mov     _dx,SYSCONFIG2
  799.         xor     _dx,[mvTranslateCode]     ; xlate the board address
  800.     in    al,dx
  801.     and    al,not bSC216bit+bSC212bit ; flush the 16 bit stuff
  802.     out    dx,al
  803. ;
  804. @@no16bit:
  805.  
  806. ;
  807. ; clear the appropriate Interrupt Control Register bit
  808. ;
  809.     mov    ah,bICsampbuff
  810.     and    ah,bICsamprate+bICsampbuff
  811.     not    ah
  812.         mov     _dx,INTRCTLR
  813.         xor     _dx,[mvTranslateCode]    ; xlate the board address
  814.     in    al,dx
  815.     and    al,ah            ; kill sample timer interrupts
  816.     out    dx,al
  817.         mov     [es:_di+MVState._intrctlr],al
  818.  
  819.         mov     al,[es:_di+MVState._crosschannel] ; get the state
  820.         mov     _dx,CROSSCHANNEL
  821.         xor     _dx,[mvTranslateCode]  ; xlate the board address
  822.     and    al,not bCCdrq        ; clear the DRQ bit
  823.     and    al,not bCCenapcm    ; clear the PCM enable bit
  824.     or    al,bCCdac
  825.     out    dx,al
  826.  
  827.         mov     [es:_di+MVState._crosschannel],al ; and save the new state
  828.  
  829.         ; Take care of common uninitialization for all mixing Sound Devices:
  830.         push    es
  831.         call    mixsdClose
  832.         pop     es
  833.         test    _ax,_ax
  834.         jnz     @@err
  835.  
  836. IFDEF __DPMI__
  837.         ; Deallocate descriptor:
  838.         call    dpmiFreeDescriptor LANG, [_int mvhwShadowPointer+INTSIZE]
  839.         test    _ax,_ax
  840.         jnz     @@err
  841.  
  842. @@nodesc:
  843. ENDIF
  844.         xor     _ax,_ax
  845.         jmp     @@done
  846.  
  847. @@err:
  848.         ERROR   ID_pasClose
  849.  
  850. @@done:
  851.     ret
  852. ENDP
  853.  
  854.  
  855. ;* $Log: pas.asm,v $
  856. ;* Revision 1.3  1997/01/16 18:41:59  pekangas
  857. ;* Changed copyright messages to Housemarque
  858. ;*
  859. ;* Revision 1.2  1996/08/04 11:32:25  pekangas
  860. ;* All functions now preserve _bx
  861. ;*
  862. ;* Revision 1.1  1996/05/22 20:49:33  pekangas
  863. ;* Initial revision
  864. ;*
  865.  
  866.  
  867. END